<script setup>
import { ref, onMounted, onBeforeUnmount, reactive, computed } from 'vue';
import '../assets/styles/mindmap.css';
import Instructions from './Instructions.vue';
import ZoomControl from './ZoomControl.vue';

// 画布状态
const scale = ref(1);
const translateX = ref(0);
const translateY = ref(0);
const isSpaceDown = ref(false);
const isLeftMouseDown = ref(false);
const dragStartX = ref(0);
const dragStartY = ref(0);
const isDragging = ref(false);

// 计算画布样式 - 只应用平移，不应用缩放
const canvasStyle = computed(() => {
  return {
    transform: `translate(${translateX.value}px, ${translateY.value}px)`,
    transformOrigin: '0 0'
  };
});

// 计算内容样式 - 只应用缩放
const contentStyle = computed(() => {
  return {
    transform: `scale(${scale.value})`,
    transformOrigin: '0 0'
  };
});

// 节点数据结构
const nodes = reactive([
  { id: 1, text: '中心主题', x: 400, y: 300, type: 'root' },
  { id: 2, text: '子主题 1', x: 600, y: 200, type: 'child' },
  { id: 3, text: '子主题 2', x: 600, y: 400, type: 'child' },
]);

// 连线数据
const connections = reactive([
  { from: 1, to: 2 },
  { from: 1, to: 3 },
]);

// 当前选中的节点
const selectedNode = ref(null);
// 第二个选中的节点（用于重新连接）
const secondSelectedNode = ref(null);

// 当前正在编辑的节点
const editingNode = ref(null);

// 编辑文本
const editText = ref('');

// 拖拽状态
const dragState = reactive({
  isDragging: false,
  startX: 0,
  startY: 0,
  nodeId: null,
});



// 清除选中状态
function clearSelection(event) {
  // 如果点击的是节点或工具栏，不清除选中状态
  if (event.target.closest('.node') || event.target.closest('.toolbar')) return;
  
  selectedNode.value = null;
  secondSelectedNode.value = null;
}

// 选择节点
function selectNode(node, event) {
  // 如果是拖拽结束，不触发选中状态的切换
  if (dragState.isDragging) return;
  
  event.stopPropagation(); // 阻止事件冒泡到容器
  
  // 如果按住Ctrl键
  if (event.ctrlKey) {
    // 如果已经选中了两个节点，不允许再选
    if (selectedNode.value && secondSelectedNode.value) return;
    
    // 如果点击的是已选中的节点，取消选中
    if (selectedNode.value && selectedNode.value.id === node.id) {
      selectedNode.value = null;
      return;
    }
    if (secondSelectedNode.value && secondSelectedNode.value.id === node.id) {
      secondSelectedNode.value = null;
      return;
    }
    
    // 设置第一个或第二个选中节点
    if (!selectedNode.value) {
      selectedNode.value = node;
    } else if (!secondSelectedNode.value) {
      secondSelectedNode.value = node;
    }
  } else {
    // 没有按Ctrl键，普通点击
    // 如果点击的是当前选中的节点，取消选中
    if (selectedNode.value && selectedNode.value.id === node.id) {
      selectedNode.value = null;
      secondSelectedNode.value = null;
      return;
    }
    
    // 更新选中状态为新节点
    selectedNode.value = node;
    secondSelectedNode.value = null;
  }
}

// 检查节点是否为孤岛
function isOrphanNode(nodeId) {
  return !connections.some(conn => conn.from === nodeId || conn.to === nodeId);
}

// 创建新连接
function createConnection() {
  if (!selectedNode.value || !secondSelectedNode.value) return;
  
  // 检查是否至少有一个是孤岛节点
  if (!isOrphanNode(selectedNode.value.id) && !isOrphanNode(secondSelectedNode.value.id)) {
    return;
  }
  
  connections.push({
    from: selectedNode.value.id,
    to: secondSelectedNode.value.id
  });
  
  // 重置选择状态
  secondSelectedNode.value = null;
}

// 删除节点
function deleteNode() {
  if (!selectedNode.value || selectedNode.value.type === 'root') return;
  
  const nodeId = selectedNode.value.id;
  
  // 删除所有相关连线
  for (let i = connections.length - 1; i >= 0; i--) {
    if (connections[i].from === nodeId || connections[i].to === nodeId) {
      connections.splice(i, 1);
    }
  }
  
  // 删除节点
  const nodeIndex = nodes.findIndex(n => n.id === nodeId);
  if (nodeIndex !== -1) {
    nodes.splice(nodeIndex, 1);
  }
  
  selectedNode.value = null;
  secondSelectedNode.value = null;
}

// 开始拖拽节点
function startDrag(event, node) {
  event.preventDefault();
  dragState.isDragging = true;
  dragState.startX = event.clientX;
  dragState.startY = event.clientY;
  dragState.nodeId = node.id;
  selectNode(node);
}

// 拖拽移动
function onDrag(event) {
  if (!dragState.isDragging) return;
  
  const dx = event.clientX - dragState.startX;
  const dy = event.clientY - dragState.startY;
  
  const node = nodes.find(n => n.id === dragState.nodeId);
  if (node) {
    node.x += dx;
    node.y += dy;
  }
  
  dragState.startX = event.clientX;
  dragState.startY = event.clientY;
}

// 结束拖拽
function endDrag() {
  dragState.isDragging = false;
}

// 处理鼠标滚轮事件
function handleWheel(e) {
  e.preventDefault();

  const rect = e.currentTarget.getBoundingClientRect();
  const mouseX = e.clientX - rect.left;
  const mouseY = e.clientY - rect.top;

  // 计算鼠标在内容中的相对位置（考虑平移但不考虑缩放）
  const mouseXInContent = mouseX - translateX.value;
  const mouseYInContent = mouseY - translateY.value;

  const delta = e.deltaY > 0 ? -0.05 : 0.05;
  const newScale = Math.max(0.1, Math.min(2, scale.value + delta));

  // 更新缩放比例，但不改变平移值
  scale.value = newScale;
}

// 放大
function zoomIn() {
  const newScale = Math.min(2, scale.value + 0.1);
  // 只更新缩放比例，不改变平移值
  scale.value = newScale;
}

// 缩小
function zoomOut() {
  const newScale = Math.max(0.1, scale.value - 0.1);
  // 只更新缩放比例，不改变平移值
  scale.value = newScale;
}

// 重置缩放
function resetZoom() {
  scale.value = 1;
  translateX.value = 0;
  translateY.value = 0;
}

// 处理鼠标按下事件
function handleMouseDown(e) {
  if (isSpaceDown.value && e.button === 0) {
    isLeftMouseDown.value = true;
    dragStartX.value = e.clientX;
    dragStartY.value = e.clientY;
    isDragging.value = false;

    document.body.style.cursor = 'grabbing';
    e.preventDefault();
  }
}

// 处理鼠标移动事件
function handleMouseMove(e) {
  if (isSpaceDown.value && isLeftMouseDown.value) {
    isDragging.value = true;

    const deltaX = e.clientX - dragStartX.value;
    const deltaY = e.clientY - dragStartY.value;

    translateX.value += deltaX;
    translateY.value += deltaY;

    dragStartX.value = e.clientX;
    dragStartY.value = e.clientY;
  }
}

// 处理鼠标抬起事件
function handleMouseUp(e) {
  if (e.button === 0 && isLeftMouseDown.value) {
    isLeftMouseDown.value = false;
    isDragging.value = false;

    document.body.style.cursor = isSpaceDown.value ? 'grab' : 'default';
  }
}

// 处理键盘按下事件
function handleKeyDown(e) {
  if (e.key === ' ' && !isSpaceDown.value) {
    isSpaceDown.value = true;
    document.body.style.cursor = isLeftMouseDown.value ? 'grabbing' : 'grab';
  } else if (e.key === 'Delete' && selectedNode.value && selectedNode.value.type !== 'root') {
    deleteNode();
  } else if (e.key === 'Escape' && editingNode.value) {
    editingNode.value = null;
  }
  // 注意：Enter键的处理逻辑已移至handleKeyUp函数
}

// 处理键盘抬起事件
function handleKeyUp(e) {
  if (e.key === ' ') {
    isSpaceDown.value = false;
    document.body.style.cursor = 'default';

    if (isLeftMouseDown.value) {
      isLeftMouseDown.value = false;
      isDragging.value = false;
    }
  } else if (e.key === 'Enter' && selectedNode.value) {
    // 在Enter键松开时调用addNode()函数，确保新节点保持编辑状态
    addNode();
  }
}

// 添加新节点
function addNode() {
  if (!selectedNode.value) return;
  
  const newId = Math.max(...nodes.map(n => n.id)) + 1;
  const offsetX = 200;
  const offsetY = 0;
  
  const newNode = {
    id: newId,
    text: '新主题',
    x: selectedNode.value.x + offsetX,
    y: selectedNode.value.y + offsetY,
    type: 'child'
  };
  
  nodes.push(newNode);
  connections.push({ from: selectedNode.value.id, to: newId });
  
  // 立即进入编辑模式
  editNode(newNode);
  
  return newNode;
}

// 编辑节点文本
function editNode(node) {
  editingNode.value = node;
  editText.value = node.text;
  
  // 在下一个事件循环中聚焦输入框
  setTimeout(() => {
    const input = document.getElementById('node-edit-input');
    if (input) input.focus();
  }, 0);
}

// 保存编辑
function saveEdit() {
  if (editingNode.value) {
    editingNode.value.text = editText.value;
    editingNode.value = null;
  }
}



// 计算连线路径 - 考虑缩放因素
function getConnectionPath(from, to) {
  const fromNode = nodes.find(n => n.id === from);
  const toNode = nodes.find(n => n.id === to);
  
  if (!fromNode || !toNode) return '';
  
  // 使用原始坐标，SVG会随内容一起缩放
  return `M ${fromNode.x} ${fromNode.y} C ${fromNode.x + 100} ${fromNode.y}, ${toNode.x - 100} ${toNode.y}, ${toNode.x} ${toNode.y}`;
}

onMounted(() => {
  window.addEventListener('mousemove', onDrag);
  window.addEventListener('mouseup', endDrag);
  document.addEventListener('keydown', handleKeyDown);
  document.addEventListener('keyup', handleKeyUp);
});

onBeforeUnmount(() => {
  document.removeEventListener('keydown', handleKeyDown);
  document.removeEventListener('keyup', handleKeyUp);
});
</script>

<template>
  <div class="mind-map-container" @wheel="handleWheel" @mousemove="handleMouseMove" @mouseup="handleMouseUp" @mousedown="handleMouseDown" @click="clearSelection" :style="{ cursor: isSpaceDown ? 'grab' : 'default' }">
    <div class="toolbar">
      <button @click="addNode" :disabled="!selectedNode">添加节点</button>
      <button @click="deleteNode" :disabled="!selectedNode || selectedNode.type === 'root'">删除节点</button>
      <button @click="createConnection" :disabled="!selectedNode || !secondSelectedNode || (!isOrphanNode(selectedNode.id) && !isOrphanNode(secondSelectedNode.id))">连接节点</button>
    </div>
    
    <div class="canvas" :style="canvasStyle">
      <!-- 连线 - 放在canvas层级，与content同级 -->
      <svg class="connections" >
        <path 
          v-for="conn in connections" 
          :key="`${conn.from}-${conn.to}`"
          :d="getConnectionPath(conn.from, conn.to)"
          class="connection-path"
          :style="contentStyle"
        />
      </svg>
      
      <!-- 内容容器 - 应用缩放 -->
      <div class="content" :style="contentStyle">
        <!-- 节点 -->
        <div 
          v-for="node in nodes" 
          :key="node.id"
          class="node"
          :class="{
            'node-root': node.type === 'root',
            'node-child': node.type === 'child',
            'node-selected': selectedNode && selectedNode.id === node.id,
            'node-second-selected': secondSelectedNode && secondSelectedNode.id === node.id,
            'node-orphan': isOrphanNode(node.id)
          }"
          :style="{ left: `${node.x}px`, top: `${node.y}px` }"
          @mousedown="startDrag($event, node)"
          @click.stop="selectNode(node, $event)"
          @dblclick="editNode(node)"
        >
        <template v-if="editingNode && editingNode.id === node.id">
          <input 
            id="node-edit-input"
            v-model="editText" 
            @blur="saveEdit"
            @keyup.enter="saveEdit"
            @keyup.esc="editingNode = null"
          />
        </template>
        <template v-else>
          {{ node.text }}
        </template>
        </div>
      </div>
    </div>
    
    <Instructions />
    <ZoomControl :scale="scale" @zoom-in="zoomIn" @zoom-out="zoomOut" @reset-zoom="resetZoom" />
  </div>
</template>

<style>
.node-second-selected {
  border-color: #4CAF50 !important;
  box-shadow: 0 0 5px rgba(76, 175, 80, 0.5);
}

.node-orphan {
  border-style: dashed !important;
}

.content {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
</style>